import { url } from 'inspector';
import { isString } from 'util';
import { PageModalService } from './page-modal-service';
import { AppGlobalService } from 'src/app/shared/service/app-global.service';
import { HttpService } from 'src/app/shared/service/http.service';
import { Injectable } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { Chooser } from '@ionic-native/chooser/ngx';
import { FilePath } from '@ionic-native/file-path/ngx';
import { Platform, ActionSheetController, LoadingController } from '@ionic/angular';
import { Camera, CameraOptions } from '@ionic-native/camera/ngx';
import { File, FileEntry } from '@ionic-native/file/ngx';
import { ImagePicker } from '@ionic-native/image-picker/ngx';
import { FileTransfer, FileUploadOptions, FileTransferObject } from '@ionic-native/file-transfer/ngx';
import { data } from 'jquery';
declare var MediaPicker;
@Injectable({
  providedIn: 'root'
})
export class UploadImageService {
  loaderToShow: any;
  maxSizeBytes = 2 * 1024 * 1024; // 2024.06.14 超过2M就压缩
  maxWidth = 912; // 2024.06.14 用于等比例压缩 最大宽度

  constructor(
    private http: HttpService,
    private appGlobalService: AppGlobalService,
    private pageModalService: PageModalService,
    // private ref: ChangeDetectorRef,
    private camera: Camera,
    private file: File,
    private platform: Platform,
    // private ref: ChangeDetectorRef,
    private actionSheetCtrl: ActionSheetController,
    private loadingController: LoadingController,
    private imagePicker: ImagePicker

  ) { }

  checkAndCompressImage(file, event, callBackFunction, blob?) {
    const that = this;
    console.log('压缩前:' + file.size);
    if (file.size > this.maxSizeBytes) {
      const compressedImage = file;
      if (blob !== undefined) {
        console.log('use blob:' + file.size);
        const reader = new FileReader();
        reader.onloadend = () => {
          // callback(reader.result);
          that.compressByReaderResult(compressedImage, reader.result, (result) => {
            const selectImg = this.convertBase64ToBlob(result);
            callBackFunction(selectImg);
          });
        };
        reader.readAsDataURL(blob);
      } else {
        console.log('use file:' + file.size);
        that.compressByReaderResult(compressedImage, event.target.result, (result) => {
          const selectImg = this.convertBase64ToBlob(result);
          callBackFunction(selectImg);
        });
      }
    } else {
      console.log('无需压缩:' + blob.size);
      if (blob) { file = blob; }
      // 文件未超过2MB，直接处理
      callBackFunction(file);
    }
  }


  compressByReaderResult(compressedImage, readerResult, callBackFunction) {
    const that = this;
    const img = new Image();
    img.onload = () => {
      console.log(new Date().toLocaleString() + '.' + new Date().getMilliseconds() + '  	need compress   ', '  	   ');
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      let width = img.width;
      let height = img.height;
      if (width > that.maxWidth) {
        height *= that.maxWidth / width;
        width = that.maxWidth;
      }
      canvas.width = width;
      canvas.height = height;
      console.log('canvas.width:' + canvas.width + "canvas.height:" + canvas.height);
      // 清除Canvas并绘制图片
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(img, 0, 0, width, height);
      // 导出压缩后的图片（这里使用base64格式）
      compressedImage = canvas.toDataURL('image/jpeg', 0.8); // 0.8是图片质量（0-1）
      callBackFunction(compressedImage);
    };

    img.src = readerResult;

  }

  dataURItoBlob(dataURI) {
    // tslint:disable-next-line:prefer-const
    let byteString = atob(dataURI.split(',')[1]);
    // tslint:disable-next-line:prefer-const
    let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    // tslint:disable-next-line:prefer-const
    let arrayBuffer = new ArrayBuffer(byteString.length);
    // tslint:disable-next-line:prefer-const
    let intArray = new Uint8Array(arrayBuffer);
    for (let i = 0; i < byteString.length; i++) {
      intArray[i] = byteString.charCodeAt(i);
    }
    return new Blob([intArray], { type: mimeString });
  }


  convertBase64ToBlob(base64: string) {
    const info = this.getInfoFromBase64(base64);
    const sliceSize = 512;
    const byteCharacters = window.atob(info.rawBase64);
    const byteArrays = [];

    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
      const slice = byteCharacters.slice(offset, offset + sliceSize);
      const byteNumbers = new Array(slice.length);

      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }

      byteArrays.push(new Uint8Array(byteNumbers));
    }

    return new Blob(byteArrays, { type: info.mime });
  }

  getInfoFromBase64(base64: string) {
    const meta = base64.split(',')[0];
    const rawBase64 = base64.split(',')[1].replace(/\s/g, '');
    const mime = /:([^;]+);/.exec(meta)[1];
    const extension = /\/([^;]+);/.exec(meta)[1];

    return {
      mime,
      extension,
      meta,
      rawBase64
    };
  }

  // App 上传文件
  async presentAction(callback, cropperRatio?) {

    {
      const actionSheet = await this.actionSheetCtrl.create({
        mode: 'ios',
        cssClass: 'as_padding as_common as_border_common',
        buttons: [{
          text: '相机',
          cssClass: 'as_font_bd',
          handler: () => {
            const source = this.camera.PictureSourceType.CAMERA;
            this.takePicture(source, false, callback, null);
          }
        }, {
          text: '从手机相册选择',
          cssClass: 'as_font_color',
          handler: () => {
            const source = this.camera.PictureSourceType.PHOTOLIBRARY;
            if (localStorage.getItem('platform') === 'android') {
              this.getMediaForAndroid(source, false, callback);
            } else {
              this.takePicture(source, false, callback, null);
            }

          }
        },
        {
          text: '取消',
          cssClass: 'as_font_top',
          handler: () => {
            console.log('Cancel clicked');
            callback("");
          }
        }]
      });
      await actionSheet.present();
    }
  }
  takePicture(sourceType, allowEdit, callback, orgPath, cropperRatio?, formItem?) {
    console.log(' message-----> 358 begin takePicture ');
    const that = this;
    const options: CameraOptions = {
      quality: 80,
      sourceType,
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      allowEdit,
      correctOrientation: true,
      saveToPhotoAlbum: false,
    };


    this.camera.getPicture(options).then((imagePath) => {
      if (orgPath !== null) {
        orgPath = imagePath;
      }
      // 不裁剪直接+水印
      if (formItem && formItem.valueN && formItem.valueN === "waterMark" && !formItem.allowCropper) {
          // 认证水印默认是选择一张图片
          console.log(orgPath);
          this.addWaterMarkUpload(orgPath, formItem, callback, "false");
      } else {
        that.startUpload(imagePath, callback, cropperRatio, formItem);
      }

    }, (err) => {
      console.log(' error-----> 372 ' + JSON.stringify(err));
      if (err === 'show setting') {
        that.pageModalService.showSettingCamera();
      }
      callback("");
    });

  }

  // fixed bug 安卓端需要使用此插件选取指定目录下的图片
  getMediaForAndroid(sourceType, allowEdit, callback, cropperRatio?) {
    console.log(' message-----> 358 begin getMediaForAndroid ');
    const that = this;
    const args = {
      maxTime: 3600, // 需求变动 改为 3600 20220128
      selectMode: 100, // 101=picker image and video , 100=image , 102=video
      maxSelectCount: 1, // default 40 (Optional)
      maxSelectSize: 58743680, // 58743680=50M (Optional)
    };
    MediaPicker.getMedias(args, (medias) => {
      if (medias && medias.length > 0) {
        that.startUpload(medias[0].uri, callback, cropperRatio);
      }
    }, (err) => {
      console.log(' error-----> take pic from album ' + JSON.stringify(err));
      if (err === 'show setting') {
        that.pageModalService.showSettingAlbum();
      }
      that.hideLoader();
      callback("");
    });
  }







  startUpload(filePath, callback, cropperRatio?, formItem?) {
    const that = this;
    if (cropperRatio && cropperRatio > 0) {
      console.log(' message-----> resolveLocalFilesystemUrl');

      this.file.resolveLocalFilesystemUrl(filePath).then(entry => {
        (entry as FileEntry).file(file => {

          const reader = new FileReader();
          reader.onloadend = () => {
            const imgBlob = new Blob([reader.result], { type: file.type });
            console.log(' openImageToCropper----->  ' + filePath);

            that.pageModalService.openImageToCropper({ url: URL.createObjectURL(imgBlob), cropperRatio },
              (res0) => {
                console.log("openImageToCropper:" + res0);
                if (res0) {
                  const currentTime = 'time' + Date.now();
                  // 裁剪后+水印
                  if (formItem && formItem.valueN === 'waterMark') {

                    that.blobToDataURI(res0, (base64) => {
                      that.addWaterMarkUploadWithBase64(base64, formItem, currentTime + ".png", callback);
                    });

                  } else {
                    const uploadData = new FormData();
                    uploadData.append('file', res0, currentTime + ".png");
                    that.uploadImageWeb(uploadData, callback);
                  }
                }
              });
          };
          reader.readAsArrayBuffer(file);

        });
      })
        .catch(err => {
          console.log(' error-----> 383 ' + JSON.stringify(err));
        });

    } else {
      this.showLoader();
      this.file.resolveLocalFilesystemUrl(filePath)
        .then(entry => {
          (entry as FileEntry).file(file => this.readFile(file, callback));
        })
        .catch(err => {
          console.log(' error-----> 383 ' + JSON.stringify(err));
          callback("");
          this.hideLoader();
        });
    }

  }

  readFile(file: any, callback) {
    console.log(' message-----> 389 begin readFile ');
    const that = this;
    const reader = new FileReader();
    reader.onloadend = (e) => {
      const formData = new FormData();
      const imgBlob = new Blob([reader.result], {
        type: file.type
      });
      // 2024.06.14 for 等比例压缩图片
      that.checkAndCompressImage(file, e, (resultFile) => {
        console.log('App 上传图片的大小：' + imgBlob.size);
        formData.append('file', resultFile, file.name);
        that.http.img_post('file/simpleUpload?waterMark=蜂喔', formData, res => {
          that.hideLoader();
          const url = res.url;
          callback(url, file.name);
        }, (error) => {
          that.hideLoader();
          that.appGlobalService.showToast('上传失败，请重试', 1500, 'middle');
          console.log(' error-----> 408 readFile ' + JSON.stringify(error));
          callback("");
        });
      }, imgBlob);

    };
    reader.readAsArrayBuffer(file);
  }


  uploadFileForWeb(selectImg: any, callback, cropperRatio?) {

    const that = this;
    if (selectImg) {
      if (typeof(selectImg) !== "object" && selectImg.indexOf('base64,') > -1) {
          const currentTime = 'time' + Date.now();
          const uploadData = new FormData();
          const mimeType = 'image/png'; // 图片的MIME类型
          const blob = this.base64ToBlob(selectImg, mimeType);
          uploadData.append('file', blob, currentTime + ".png");
          that.uploadImageWeb(uploadData, callback);
      } else if (['jpeg', 'png', 'jpg'].indexOf(selectImg.type.split('/')[1]) > -1) {
        if (cropperRatio && cropperRatio > 0) {

          const currentTime = 'time' + Date.now();
          that.pageModalService.openImageToCropper({ url: URL.createObjectURL(selectImg), cropperRatio },
            (res0) => {
              console.log("openImageToCropper:" + res0);
              if (res0) {
                const uploadData = new FormData();
                uploadData.append('file', res0, currentTime + ".png");
                that.uploadImageWeb(uploadData, callback);
              }
            });

        } else {
          const reader = new FileReader();
          reader.onloadend = (e) => {
            const uploadData = new FormData();
            const imgBlob = new Blob([reader.result], {
              type: selectImg.type
            });
            // 2024.06.14 for 等比例压缩图片
            that.checkAndCompressImage(selectImg, e, (resultFile) => {
              uploadData.append('file', resultFile, selectImg.name);
              that.uploadImageWeb(uploadData, callback);
            }, imgBlob);
          };
          reader.readAsArrayBuffer(selectImg);
          reader.onerror = (e) => { that.hideLoader(); };

        }
      } else {
        this.appGlobalService.showToast('格式不正确，请选择图片', 3000, 'middle');
      }
    }
  }
  uploadImageWeb(uploadData, callback) {
    const that = this;
    this.showLoader();
    that.http.img_post('file/simpleUpload?waterMark=蜂喔', uploadData, res => {
      that.hideLoader();
      let url = JSON.stringify(res.url).toString();
      console.log('message----->' + url);
      url = url.replace('"', '').replace('"', '');
      callback(url);
    }, err => {
      that.hideLoader();
      that.appGlobalService.showToast('上传失败，请重试', 1500, 'middle');

      callback("");
    });
  }

  showLoaderWithMsg(ref, msg?) {
    this.loaderToShow = this.loadingController.create({
      message: msg ? msg : '上传文件中...'
    }).then((res) => {
      res.present();
      res.onDidDismiss().then((dis) => {
        ref.detectChanges(); // trigger change detection cycle
      });
    });
  }

  // 2024.06.14 整合所有选择相册 maxSelectImageCount:最大选择图片数量，orgPath:原图片地址，tagData[allowCropper,allowEdit]:允许裁剪
  openImgPicker(callBackFunction, maxSelectImageCount, isCompleteBatchUpload, orgPath, tagData, changeDetectorRef) {
    const that = this;
    // 2024.05.29 android
    if (localStorage.getItem('platform') === 'android') {
      const args = {
        maxTime: 3600, // 需求变动 改为 3600 20220128
        selectMode: 100, // 101=picker image and video , 100=image , 102=video
        maxSelectCount: maxSelectImageCount, // default 40 (Optional)
        maxSelectSize: 58743680, // 58743680=50M (Optional)
      };
      MediaPicker.getMedias(args, (medias) => {
        isCompleteBatchUpload = medias.length;
        if (medias && medias.length > 0) {
          // that.showLoaderWithMsg(changeDetectorRef, '图片上传中...');
          orgPath = medias[0];
          if (tagData.valueN && tagData.valueN === "waterMark" && !tagData.allowCropper) {
            this.addWaterMarkUpload(medias[0].uri, tagData, callBackFunction);
          } else {
            if (tagData.allowCropper && maxSelectImageCount === 1) {
              this.startUpload(medias[0].uri, callBackFunction, tagData.cropperRatio , tagData);
            } else {
              for (let i = 0; i < medias.length; i++) {
                that.file.resolveLocalFilesystemUrl(medias[i].uri)
                  .then(async entry => {
                    (entry as FileEntry).file(file => that.readFileForBatch(file, i, medias[i], isCompleteBatchUpload, callBackFunction));
                  })
                  .catch(async err => {
                    that.hideLoader();
                    console.log(' error-----> 596 ' + JSON.stringify(err));
                  });
              }
            }
          }
        }

      }, (err) => {
        that.hideLoader();
        console.log(' error-----> take pic from album ' + JSON.stringify(err));
        if (err === 'show setting') {
          that.pageModalService.showSettingAlbum();
        }
      });


    } else {

      if (tagData.allowCropper || (tagData.allowEdit && maxSelectImageCount === 1)) {
        const source = this.camera.PictureSourceType.PHOTOLIBRARY;
        that.takePicture(source, tagData.allowEdit, callBackFunction, orgPath, tagData.cropperRatio, tagData);
      } else {
        that.imagePicker.getPictures({
          maximumImagesCount: maxSelectImageCount,
          // width: 1024,
          // height: 1024,
          quality: 80,
          outputType: 0
        }).then(
          (results) => {
            isCompleteBatchUpload = results.length;
            if (results.length > 0) {
              orgPath = results[0];
              
              if (tagData.valueN && tagData.valueN === "waterMark") {
                // 认证水印默认是选择一张图片
                console.log(results[0]);
                that.addWaterMarkUpload(orgPath, tagData, callBackFunction);
              } else {
                that.showLoader(changeDetectorRef);
                for (let i = 0; i < results.length; i++) {
                  that.file.resolveLocalFilesystemUrl(results[i])
                    .then(async entry => {
                  (entry as FileEntry).file(file => that.readFileForBatch(file, i, results[i], isCompleteBatchUpload, callBackFunction));
                    })
                    .catch(async err => {
                      that.hideLoader();
                      console.log(' error-----> 596 ' + JSON.stringify(err));
                    });
                }
              }
            }
          }, (err) => {
            that.hideLoader();
            console.log(' error-----> 601 ' + JSON.stringify(err));
            that.pageModalService.showSettingAlbum();

          }
        );
      }
    }

  }


  // 2024.06.14 取base64
  arrayBufferToBase64(buffer) {
    let binary = '';
    const bytes = new Uint8Array(buffer);
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
  }

  readFileForBatch(file: any, countNum: any, item: any, isCompleteBatchUpload, callBackFunction) {
    const that = this;
    console.log(' message-----> 456 begin readFileForBatch that.isCompleteBatchUpload is' + isCompleteBatchUpload);
    const reader = new FileReader();
    reader.onloadend = (e) => {
      const formData = new FormData();
      const imgBlob = new Blob([reader.result], {
        type: file.type
      });
      that.checkAndCompressImage(file, e, (resultFile) => {
        formData.append('file', resultFile, file.name);
        that.http.img_post('file/simpleUpload?waterMark=蜂喔', formData, res => {
          console.log(' message-----> 466 upload img[' + (countNum + 1) + '] success ');
          const url = res.url;

          // 2024.06.14上传成功回调处理具体业务
          callBackFunction(url, file.name);
          that.hideLoader();
        }, (error) => {
          console.log(' error-----> img_post： ' + JSON.stringify(error));
          
          that.hideLoader();
          that.appGlobalService.showToast('上传失败，请重试', 1500, 'middle');
        });
      }, imgBlob);

    };
    reader.readAsArrayBuffer(file); // readAsArrayBuffer(file);
    reader.onerror = (e) => { that.hideLoader(); };
  }
  showLoader(ref?) {
    this.loaderToShow = this.loadingController.create({
      message: '上传文件中...'
    }).then((res) => {
      res.present();
      res.onDidDismiss().then((dis) => {
        if (ref) {
          ref.detectChanges(); // trigger change detection cycle
        }
        // this.ref.detectChanges(); // trigger change detection cycle
      });
    });
    // this.hideLoader();
  }
  hideLoader() {
    setTimeout(() => {
      if (this.loadingController) {
        this.loadingController.dismiss();
      }
    }, 1000);
  }

  // blob 转 base64
  blobToDataURI(blob, callback) {
    const reader = new FileReader();
    reader.onloadend = () => {
      // 读取完成后，将base64编码的字符串赋值给base64变量
      const base64 = reader.result;
      callback(base64);
    };
    reader.readAsDataURL(blob);
  }

  base64ToBlob(base64, mimeType) {
    const byteCharacters = atob(base64.split(',')[1]);
    const byteArrays = [];
    for (let offset = 0; offset < byteCharacters.length; offset += 512) {
      const slice = byteCharacters.slice(offset, offset + 512);
      const byteNumbers = new Array(slice.length);
      for (let i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }
      const byteArray = new Uint8Array(byteNumbers);
      byteArrays.push(byteArray);
    }
    return new Blob(byteArrays, {type: mimeType});
  }

  addWaterMarkUploadWithBase64(base64Image0, formItem, fileName , callback){
    const sourceImage = base64Image0; // 原图
    let watermarkImage = 'assets/fw/fengworz.png'; // 默认水印图片路径
    // 支持配置水印
    if (formItem.showValue && formItem.showValue.length > 0) {
      watermarkImage = formItem.showValue;
    }
    this.appGlobalService.addWatermark(sourceImage, watermarkImage, (base64Image) => {
      console.log(base64Image);
      // 处理后的图片是base64编码的，可以直接上传
      this.uploadFileForWeb(base64Image, (url: any) => {
        this.hideLoader();
        console.log('message----->' + url);
        url = url.replace('"', '').replace('"', '');
        callback(url, fileName);
      });
    });
  }

  addWaterMarkUpload(orgPath, formItem, callback, showLoading?) {
    const that = this;
    // if (showLoading && showLoading === "false") {

    // } else {
    //   this.showLoader();
    // }

    that.file.resolveLocalFilesystemUrl(orgPath)
              .then(async entry => {

                (entry as FileEntry).file(file0 => {
                    // 将文件转base64
                  // 找到最后一个斜杠的位置
                  const lastIndex = file0.localURL.lastIndexOf('/');
                  let  directoryPath = "";
                  // 如果找到了斜杠，则截取路径部分
                  if (lastIndex !== -1) {
                    directoryPath = file0.localURL.slice(0, lastIndex + 1); // 加1是为了包含斜杠
                    console.log(directoryPath);
                  } else {
                      console.log("No directory separator found in the file path.");
                      that.hideLoader();
                      return;
                  }
                  that.file.readAsDataURL(directoryPath, file0.name).then(base64Image0 => {
                    console.log("原图：" + base64Image0);
                    that.addWaterMarkUploadWithBase64(base64Image0, formItem, orgPath.name , callback);

                  }).catch(async err => {
                    that.hideLoader();
                    console.log(' readAsDataURL error----->  ' + JSON.stringify(err));
                  });

                  }
                );
              })
              .catch(async err => {
                that.hideLoader();
                console.log(' error-----> 596 ' + JSON.stringify(err));
              });

  }
}
